/**
 *
 */
package com.naiterui.ehp.bs.doctor.dao.impl;

import com.naiterui.ehp.bp.domain.DoctorCharge;
import com.naiterui.ehp.bp.domain.DrChargeConfig;
import com.naiterui.ehp.bp.domain.DrMessageConsultCharge;
import com.naiterui.ehp.bp.domain.DrMessageConsultChargePK;
import com.naiterui.ehp.bs.doctor.dao.IDrMessageConsultChargeDao;
import com.naiterui.ehp.bs.doctor.repository.IDoctorChargeRepository;
import com.naiterui.ehp.bs.doctor.repository.IDrMessageConsultChargeRepository;
import com.naiterui.ehp.bs.doctor.vo.PatientMessageChargeVO;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 医生图文咨询收费持久层
 *
 * @author guoyongxiang
 * @since 2.7.0
 */
@Component
public class AdDrMessageConsultChargeDaoImpl implements IDrMessageConsultChargeDao {

    @Autowired
    private IDrMessageConsultChargeRepository drMessageConsultChargeRepository;
    @Autowired
    private IDoctorChargeRepository doctorChargeRepository;

    @Override
    public Integer getChargeById(Long doctorId, Long patientId) {
        /*DrMessageConsultChargePK chargePK = new DrMessageConsultChargePK();
        chargePK.setDoctorId(doctorId);
        chargePK.setPatientId(patientId);
        DrMessageConsultCharge drMessageConsultCharge = drMessageConsultChargeRepository.get(chargePK);
        if (drMessageConsultCharge != null) {
            return drMessageConsultCharge.getCharge();
        }
        return 0;*/

        // 诊费统目前走医生统一设置结构
        DoctorCharge doctorCharge = doctorChargeRepository.findFirstByDoctorIdAndChargeType(doctorId, DrChargeConfig.TYPE_MESSAGE);
        return Optional.ofNullable(doctorCharge).map(DoctorCharge::getCharge).orElse(0);
    }


    /**
     * 根据医生id和患者列表获取收费金额列表(
     * DrMessageConsultChargeDaoImpl.getChargeListByDoctorId()
     *
     * @param doctorId
     * @return
     *
     * @Author guoyongxiang
     * @Date 2017年4月11日
     * @since 2.7.0
     */
    @Override
    public Map<Long, Integer> getChargeListByDoctorId(Long doctorId, List<Long> patientIds) {
        /*List<DrMessageConsultCharge> chargeList = drMessageConsultChargeRepository.getChargeListByDoctorId(doctorId);

        Map<Long, Integer> patientMap = Optional.ofNullable(chargeList).orElse(Lists.newArrayList()).stream()
                                                .collect(Collectors.toMap(charge -> charge.getChargePK().getPatientId(),
                                                        DrMessageConsultCharge::getCharge, (a, b) -> b));
        return patientMap;*/
        
        // 诊费统目前走医生统一设置结构
        Integer charge = getChargeById(doctorId , 0L);
        return patientIds.stream().collect(Collectors.toMap(Function.identity(),id -> charge));
    }

    /**
     * 极限测试：
     * 本地48000条数据SSD硬盘MacPro插入约11秒，查询300毫秒，可将saveOrUpdate优化为区分开insert与update，将update使用一条语句批量更新，将节约大量时间，测试时一条update
     * 语句更新48000条数据大约耗时300毫秒。
     * 由于目前实际业务量场景，为避免使业务变复杂，暂不考虑极限情况，以上方案供后续优化参考使用。
     *
     * @param doctorId
     * @param changeVOList
     *
     * @Author guoyongxiang
     * @Date 2017年3月31日
     * .util.Set)
     * @since 2.7.0
     */
    @Override
    public void saveChargeByDoctorId(Long doctorId, Set<PatientMessageChargeVO> changeVOList) {

        if (changeVOList != null && changeVOList.size() > 0) {

            List<DrMessageConsultCharge> list = changeVOList.stream()
                                                    .map(vo -> {
                                                        DrMessageConsultCharge charge = new DrMessageConsultCharge();
                                                        DrMessageConsultChargePK chargePK = new DrMessageConsultChargePK();
                                                        chargePK.setDoctorId(doctorId);
                                                        chargePK.setPatientId(vo.getPatientId());
                                                        charge.setChargePK(chargePK);
                                                        charge.setCharge(vo.getCharge());
                                                        charge.setCreatedAt(new Date());
                                                        charge.setCreatedBy("doctorSystem");
                                                        return charge;
                                                    }).collect(Collectors.toList());
            drMessageConsultChargeRepository.save(list);
        }

    }

    @Override
    public void deleteChareByDoctorId(Long doctorId) {
        DrMessageConsultChargePK chargePK = new DrMessageConsultChargePK();
        chargePK.setDoctorId(doctorId);
        drMessageConsultChargeRepository.deleteById(chargePK);
    }

    @Override
    public void deleteChareByDoctorId(Long doctorId, Set<Long> patientIds) {
        List<DrMessageConsultChargePK> list = patientIds.stream().map(s -> {
            DrMessageConsultChargePK chargePK = new DrMessageConsultChargePK();
            chargePK.setDoctorId(doctorId);
            chargePK.setPatientId(s);
            return chargePK;
        }).collect(Collectors.toList());
        drMessageConsultChargeRepository.deleteByChargePKIn(list);
    }

    /**
     * 根据患者id及医生id列表查询该患者对应医生的诊金
     *
     * @param doctorIds 医生id
     * @param patientId 患者id
     * @return
     */
    @Override
    public Map<Long, Integer> getChargeListByPatientId(List<Long> doctorIds, Long patientId) {

        List<DrMessageConsultChargePK> idList = doctorIds.stream().map(s -> {
            DrMessageConsultChargePK chargePK = new DrMessageConsultChargePK();
            chargePK.setDoctorId(s);
            chargePK.setPatientId(patientId);
            return chargePK;
        }).collect(Collectors.toList());
        Iterator<DrMessageConsultCharge> chargeList = drMessageConsultChargeRepository.findAllById(idList).iterator();
        Map<Long, Integer> doctorMap = new HashMap<>();
        while (chargeList.hasNext()){
            DrMessageConsultCharge charge = chargeList.next();
            doctorMap.put(charge.getChargePK().getDoctorId(), charge.getCharge());
        }
        return doctorMap;
    }

}
